#include "CarStop.h"
#include <iostream>

std::string GetTimeStr(time_t time)
{
    tm *m = localtime(&time);
    char s[1024] = {0};
    sprintf(s, "%d年%d月%d日 %d:%d:%d", m->tm_year + 1900, m->tm_mon + 1, m->tm_mday, m->tm_hour, m->tm_min, m->tm_sec);
    return std::string(s);
}

CarStop::~CarStop()
{
    while (stop.IsEmpty() == false)
    {
        Car *c = (Car *)*stop.GetTop();
        delete c;
        stop.Pop();
    }
    while (pavement.IsEmpty() == false)
    {
        Car *c = (Car *)*pavement.GetFront();
        delete c;
        pavement.Pop();
    }
}

void CarStop::ComeCar()
{
    Car *c = new Car("");
    std::cout << "请输入车牌:";
    std::cin >> c->Name;

    c->arriveTime = time(nullptr); // 获取到达时间
    std::cout << "车辆|" << c->Name << "在" << GetTimeStr(c->arriveTime) << "到达停车场";

    if (stop.Size() == size)
    {
        std::cout << "停车场已满." << c->Name << "停在便道上第" << pavement.Size() + 1 << "个位置" << std::endl;
        pavement.Push(c);
    }
    else
    {
        std::cout << "停车场未停满,停入停车场第" << stop.Size() + 1 << "个位置" << std::endl;
        stop.Push(c);
    }
}

void CarStop::LeaveCar()
{
    std::cout <<"请输入要离开的车辆:";
    std::string LeaveCarName;
    std::cin >> LeaveCarName;
    LinkStack tmpStop; // 临时栈
    while (stop.IsEmpty() == false)
    {
        Car *c = (Car *)*stop.GetTop();  // 获取栈顶的车辆，一直获取到找到需要删除的车辆为止(目的是找到要离场的车)
        stop.Pop();// 使其出栈
        if (c->Name == LeaveCarName) // 找到要离场的车 
        {
            c->leaveTime = time(nullptr);            
            double money = 1.0 * (c->leaveTime - c->arriveTime) / 3600 * 200;   // 计算停车费用
            std::cout << "车辆|" << c->Name << "|于"
                      << GetTimeStr(c->leaveTime)
                      << "离开停车场，停车费用|"
                      << money << "|元" << std::endl;
            delete c;
            break;
        }
        tmpStop.Push(c); // 放临时栈中
    }
    while (tmpStop.IsEmpty() == false)
    {
        stop.Push(*tmpStop.GetTop());  // 将不需要删除的车辆再放入停车场中
        tmpStop.Pop();  // 释放掉临时栈中的车辆
    }

    // 停车场有车位，且便道上有车，便让便道上的车进入
    if (stop.Size() < size && pavement.IsEmpty() == false)
    {
        Car *c = (Car *)*pavement.GetFront();  // 找到停车场中队列前面的车
        c->arriveTime = time(nullptr);

        std::cout << "便道上的车|" << c->Name << "在" << GetTimeStr(c->arriveTime) << "进入停车场" << std::endl;
        pavement.Pop();  // 在便道上移除
        stop.Push(c);   // 放入停车场中
    }
}

void CarStop::show()
{
    LinkStack tmpStop;
    while (stop.IsEmpty() == false)
    {
        tmpStop.Push(*stop.GetTop());
        stop.Pop();
    }

    while (tmpStop.IsEmpty() == false)
    {
        Car *c = (Car *)*tmpStop.GetTop();
        std::cout << "🚗|" << c->Name << "|" << std::endl;
        stop.Push(c);
        tmpStop.Pop();
    }
    std::cout << std::endl;

    LinkQueue tmpPavement;
    while (pavement.IsEmpty() == false)
    {
        tmpPavement.Push(*pavement.GetFront());
        pavement.Pop();
    }
    while (tmpPavement.IsEmpty() == false)
    {
        Car *c = (Car *)*tmpPavement.GetFront();
        std::cout << "              🚗|" << c->Name << "|" << " ";
        pavement.Push(c);
        tmpPavement.Pop();
    }
}
